﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BIZMA._controls;
using BIZModel;
using BL.BIZControls;
using System.Web.Security;

namespace BIZMA._controls.DemoProject
{
    public partial class List_ProjectMembers : BIZListControl, IBIZControlDefaultMethods
    {
        #region Default
        public void DefaultListLoad()
        {
            throw new NotImplementedException();
        }
        public void DefaultListLoad(Guid Id, string loadByType)
        {
            if (loadByType == null || loadByType == ObjectTypeProject)
            {
                LoadProjectMembers(Id);
            }
            else
            {
                throw new ArgumentException("No matching type in loadByType. Use appropriate ObjectType... constant");
            }
        }

        public void DefaultEditNew()
        {
            throw new NotImplementedException();
        }

        public void DefaultEditNew(Guid Id, string editByType)
        {
            throw new NotImplementedException();
        }

        public void DefaultEditLoad(Guid Id)
        {
            throw new NotImplementedException();
        }

        #endregion

        //Skapa objecttyper för att beskriva objekt i generella funktioner
        /// <summary>
        /// ObjectType för kund används där typ av objekt ska beskrivas tex i generella metoder där bara ett id och objettype finns
        /// </summary>
        public const string ObjectTypeProject = "PROJECT";

        //Skapa eventtyper för att beskriva vilket event som sker i generella eventfunktioner
        public const string EventTypeOpenUserDetail = "OpenUserDetail";
        public const string EventTypeOpenSelectUsers = "OpenSelectUsers";


        //Properties för att hålla reda på om en dialog kan öppnas eller om den redan är öppen i en underliggande dialog
        private bool CanAddUserListPopup { get { return ViewState["CanAddUserListPopup"] != null ? (bool)ViewState["CanAddUserListPopup"] : true; } set { ViewState["CanAddUserListPopup"] = value; } }
        private bool CanAddUserEdtiPopup { get { return ViewState["CanAddUserEdtiPopup"] != null ? (bool)ViewState["CanAddUserEdtiPopup"] : true; } set { ViewState["CanAddUserEdtiPopup"] = value; } }


        //OLIKA ID properties som styr frågan för listan tex om man ska hämta utifrån EmployeeId eller PlanningId
        //Styrs av publika metoder
        //--
        private Guid ProjectId { get { return ViewState["ProjectId"] != null ? (Guid)ViewState["ProjectId"] : Guid.Empty; } set { ViewState["ProjectId"] = value; } }

        //Olika filter för frågan till listan kan tex vara om man ska visa alla eller aktiva, eller datum mmm
        //Filter sätter man innan man kör de publika metorder som sätter ID properties som finns ovan
        /// <summary>
        /// Sök efter förnamn som innehåller detta
        /// </summary>
        public string FilterBy_FirstName { get { return ViewState["FilterBy_FirstName"] != null ? (string)ViewState["FilterBy_FirstName"] : ""; } set { ViewState["FilterBy_FirstName"] = value; } }
        /// <summary>
        /// Sök efter efternamn som innehåller detta
        /// </summary>
        public string FilterBy_LastName { get { return ViewState["FilterBy_LastName"] != null ? (string)ViewState["FilterBy_LastName"] : ""; } set { ViewState["FilterBy_LastName"] = value; } }
        

        #region Init
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack || !InitLoaded)
            {
                ApplySettings();
                //Gör sådant som man gör på pageload här typ fyll "statisk" dropdown med värden mm 
                //Väldigt ovanligt att man laddar listan härifrån då det oftast görs via en annan metod se public void LOAD_BY_SOMETHING_LIST(int someval)
            }

            //Vill man lyssna på specifika event från laddade kontroller ska det reggas här
            //OnInit sker innan så då är Container.ContainedControl alltid null eftersom kontrollerna i denna inte är laddade ännu
            if (mcSelectUsers.ContainedListControl != null)
            {
                mcSelectUsers.ContainedListControl.ListSelect += new SelectedChanged(NewMembersSelect);
            }

        }



        protected override void OnInit(EventArgs e)
        {
            //här gör man alla init inställningar tex lägga till eventhandlers och annat som styr sidan
            //Peka ut dropdown för basklassen
            base.ActionDropDown = ddlAction;
            //Peka ut listkontrollen för basklassne
            base.ListControl = lv;
            //Kör om formpart har fler än 1 rad
            //base.SetFormPartHeight(2);

            base.OnInit(e);

            //Event när basklassen behöver listdatat
            base.NeedsData += new NeedsDataHandler(List_NeedsData);
            //Basklassen kör ItemDatabound och triggar detta event efter att varje rad har hanterats i basklassen 
            ListDataBound += new EventHandler<ListViewItemEventArgs>(List_ListDataBound);


            if (ContainerControl != null)
            {
                //Titel på Caontainerkontrollen
                ContainerControl.Title = "Projektmedlemmar";
                //Event vid klick på knapparna i containerkontrollen
                //ContainerControl.ButtonsClick += new ButtonsHandler(ContainerControl_ButtonsClick);
                //Vilka knappar som ska visas
                ContainerControl.ShowButtons(false, false, false, false);

                //Om container är en modal dialog
                if (ModalContainerControl != null)
                {
                    ModalContainerControl.Width = 800;
                    ModalContainerControl.Height = 500;
                    //Event om storlek på modalakontrollen ändras kan användas för att justera storlek på andra element i kontrollen
                    ModalContainerControl.FormScrollStyleChanged += new EventHandler(ModalContainerControl_FormScrollStyleChanged);
                }

                CanAddUserListPopup = mcSelectUsers.CanAddPopupControl(BIZControl.UserList);
                CanAddUserEdtiPopup = mcEditUser.CanAddPopupControl(BIZControl.User);
            }

            //Event när detaljdialogen stänger
            mcEditUser.ModalClosing += new ModalControlClosing(mcEditUser_ModalClosing);

            btnAdd.Click += new EventHandler(btnAdd_Click);


        }



        /// <summary>
        /// Utför ändringar i kontrollen utifrån de inställningar som gjort tex MultiSelect, PickerControl, Edit mm
        /// Funktionen körs automatiskt när listan laddas om den inte kört innan
        /// Exempel på hur man använder
        /// Skapa ett event på att kontrollen laddas (men gör det i metoden där kontrollen läggs till eftersom du bara vill trigga detta en gång)
        /// mContainer.BIZControlLoaded += new ControlLoaded(mContainer_BIZControlLoaded);
        /// mContainer.AddDefaultListLoad(BIZControl.FolderList, SelectedId, List_Folders.LoadByCheckRootOnSected);
        /// 
        /// Gör lite inställningar på kontrollen tex:
        /// ((List_Folders)mContainer.ContainedControl).MultipleSelect = false;
        /// ((List_Folders)mContainer.ContainedControl).SelectedItems.Clear();
        /// ((List_Folders)mContainer.ContainedControl).SelectedItems.Add(SelectedId);
        /// </summary>
        public void ApplySettings()
        {
            //Gör sådant som man gör på pageload här typ fyll "statisk" dropdown med värden mm 
            InitLoaded = true;
            FillActionList();
        }


        /// <summary>
        /// Fyller dropdown med värden
        /// </summary>
        private void FillActionList()
        {
            //TODO:RÄTTIGHETER

            ddlAction.Items.Add(new ListItem("--Välj åtgärd--", "-"));
            if (PickerControl)
            {
                ddlAction.Items.Add(new ListItem("Välj", "SEL"));
                ddlAction.Items.Add(new ListItem("-------", "-"));
            }
            ddlAction.Items.Add(new ListItem("Radera", "DEL"));

        }

        /// <summary>
        /// Aktiverar/inaktiverar knappar som behöver data eller som inte kan visas pga underliggande dialoger 
        /// </summary>
        private void ToggleButtons()
        {
            //Sätt status om knappen kan visas pga underliggande dialoger
            BaseBL.BtnOpenEnabled(btnAdd, CanAddUserListPopup, ViewState);           
        }

        #endregion
        #region Container Events
        /// <summary>
        /// Event när Container ändrar storlek
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ModalContainerControl_FormScrollStyleChanged(object sender, EventArgs e)
        {
            //ListScroll Height sätts automatiskt i basklassen 
        }

        void List_NeedsData(bool sorting)
        {
            LoadList(sorting);
        }

        ///// <summary>
        ///// Triggas vid klick på någon av containerkontrollens knappar
        ///// </summary>
        ///// <param name="sender">Containerkontrollen</param>
        ///// <param name="actionType">Vilken typ av knapp som klickats</param>
        //void ContainerControl_ButtonsClick(object sender, ActionType actionType)
        //{
        //    if (actionType == ActionType.Save || actionType == ActionType.SaveClose)
        //    {
        //        Save();
        //    }
        //    else if (actionType == ActionType.Delete)
        //    {
        //        Delete();
        //    }
        //}


        #endregion

        #region Events This Control
        /// Event  när man har knappar för att välja en rad i listan
        /// </summary>
        /// <param name="sender">Knappen som klickats</param>
        /// <param name="e">Knappens CommandEventArgs</param>
        protected void btnSel_Command(object sender, CommandEventArgs e)
        {
            SelectedItems = new List<Guid>();
            SelectedItems.Add(Guid.Parse(e.CommandArgument.ToString()));

            //Kör denna metod så att containercontrollen kan trigga ett SelectEvent tillbaka till sidan med containern 
            CallListSelect(this, null, MultipleSelect, SelectedItems);

        }
        /// <summary>
        /// Event när man har valt en/flera rader i listan och väljer att utföra något från åtgärdslistan tex (Välj eller radera) 
        /// </summary>
        /// <param name="sender">Knappen utför</param>
        /// <param name="e">EventArgs. Används inte det är vad man valt i ddlAction som är intressant</param>
        protected void btnAction_Click(object sender, EventArgs e)
        {
            if (ddlAction.SelectedValue != "-")
            {
                if (ddlAction.SelectedValue == "SEL")
                {
                    var selectedKeys = lv.GetSelectedDataKeys("chkSel");
                    SelectedItems = new List<Guid>();
                    foreach (DataKey dk in selectedKeys)
                    {
                        Guid selId = Guid.Parse(dk.Value.ToString());
                        SelectedItems.Add(selId);
                    }

                    CallListSelect(this, null, MultipleSelect, SelectedItems);
                }
                else
                {

                    var selectedKeys = lv.GetSelectedDataKeys("chkSel");
                    BIZMAEntities ent = BaseBL.GetEnt();

                    //Radera vala objekt i listan                    
                    if (ddlAction.SelectedValue == "DEL")
                    {
                        List<Guid>UserIds = selectedKeys.Cast<Guid>().ToList();

                       //List<Guid>UserIds = selectedKeys.ConvertAll<Guid>(delegate(DataKey DK){return Guid.Parse(DK.Value.ToString());});


                        foreach (ProjectMember PM in ent.ProjectMembers.Where(q => q.ProjectId == ProjectId && UserIds.Contains(q.UserId)))
                        {
                            ent.DeleteObject(PM);
                        }


                        //Project project = ent.Projects.FirstOrDefault(q => q.ProjectId == ProjectId);

                        //foreach (DataKey dk in selectedKeys)
                        //{
                        //    //Radera kopplingen mellan projekt och user
                        //    Guid selId = Guid.Parse(dk.Value.ToString());
                        //    UserProfile projectMember = project.UserProfiles.FirstOrDefault(q => q.UserId == selId);
                           
                        //    project.UserProfiles.Remove(projectMember);  
                        //}
                    }

                    ent.SaveChanges();
                }
            }

            LoadList(false);

        }

        /// <summary>
        /// Event för klick på sökfunktionen
        /// </summary>
        /// <param name="sender">Knappen</param>
        /// <param name="e">Knappens EventArgs</param>
        protected void btnSearch_Click(object sender, EventArgs e)
        {
            FilterBy_FirstName = txtSearchFirstName.Text;
            FilterBy_LastName = txtSearchLastName.Text;

            LoadList(true);
        }


        #endregion


        #region Control and List methods
        /// <summary>
        /// Här rensas alla id properties som används för frågan till listan
        /// </summary>
        private void ResetIdProperties()
        {
            lv.DataSource = null;
            lv.DataBind();
            ProjectId = Guid.Empty;
        }
        /// <summary>
        /// Laddar listan
        /// </summary>
        public void LoadProjectMembers(Guid projectId )
        {
            ResetIdProperties();
            ProjectId = projectId;
            LoadList(true);

        }
        /// <summary>
        /// Nollställ kontrollen och töm listan på värden
        /// </summary>
        public void Clear()
        {
            ResetIdProperties();
        }

        public void AddUsers(List<Guid> userIds)
        {
            if (ProjectId == Guid.Empty)
            {
                throw new ArgumentNullException("ProjectId is missing, You need to run LoadProjectMembers first to the current project");
            }

            BIZMAEntities ent = BaseBL.GetEnt();
            Project project = ent.Projects.FirstOrDefault(q => q.ProjectId == ProjectId);


            List<Guid> existUsers = ent.ProjectMembers.Where(q => q.ProjectId == ProjectId && userIds.Contains(q.UserId)).Select(s => s.UserId).ToList();
            
            userIds.RemoveAll(q => existUsers.Contains(q)); 
                   
            foreach(Guid userId in userIds)
            {
                ProjectMember PM = ProjectMember.CreateProjectMember(ProjectId,userId);

                ent.ProjectMembers.AddObject(PM);
                           
            }
           
            ent.SaveChanges();

        }

        /// <summary>
        /// Metod som ansvarar för att fylla listan med värden utifrån vilken publik load metod som körts innan
        /// </summary>
        /// <param name="sorting">Talar om ifall sortering ska ändras eller om man ska använda tidigare sortering</param>
        private void LoadList(bool sorting)
        {
            InitLoaded = true;

            BIZMAEntities ent = BaseBL.GetEnt();
            IQueryable<BIZModel.UserProfile> query = ent.UserProfiles.Where(q => q.ProjectMembers.FirstOrDefault(sq => sq.ProjectId == ProjectId) != null);

            if (query != null)
            {
                if (FilterBy_FirstName != "")
                {
                    query = query.Where(q => q.FirstName.Contains(FilterBy_FirstName));
                }
                if (FilterBy_LastName != "")
                {
                    query = query.Where(q => q.LastName.Contains(FilterBy_LastName));
                }
            }

            lv.DataSource = (from BIZModel.UserProfile Q in query
                             select new
                             {
                                 Q.UserId,
                                 Q.FirstName,
                                 Q.LastName
                             });

            lv.DataBind();

            if (!sorting)
                lv.ReSort(ViewState);
        }

        /// <summary>
        /// Event för varje rad som laddas i listan
        /// </summary>
        /// <param name="sender">Listan</param>
        /// <param name="e">ListViewItemEventArgs</param>
        void List_ListDataBound(object sender, ListViewItemEventArgs e)
        {
            LinkButton lkb1 = (LinkButton)e.Item.FindControl("lkb1");
            LinkButton lkb2 = (LinkButton)e.Item.FindControl("lkb2");

            BaseBL.BtnOpenEnabled(lkb2, CanAddUserEdtiPopup, ViewState);
            BaseBL.BtnOpenEnabled(lkb2, CanAddUserEdtiPopup, ViewState);
        }

        #endregion

        #region sub dialog event and methods
        /// <summary>
        /// Klickar för att öppna detaljvy från listan
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">CommandEventArgs</param>
        protected void OpenDetail_Command(object sender, CommandEventArgs e)
        {
            if (HandleListClickEvents)
            {
                CallHandleClick(this, Guid.Parse(e.CommandArgument.ToString()), EventTypeOpenUserDetail);
            }
            else
            {
                if (CanAddUserListPopup)
                {
                    mcEditUser.AddDefaultEditLoad(BIZControl.User, Guid.Parse(e.CommandArgument.ToString()));
                }
            }

        }

        /// <summary>
        /// Klickar för att lägga till nytt i listan
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        void btnAdd_Click(object sender, EventArgs e)
        {
            if (HandleNewClickEvent)
            {
                CallNewHandleClick(this, Guid.Empty, EventTypeOpenSelectUsers);
            }
            else
            {
                if (CanAddUserListPopup)
                {
                    mcSelectUsers.AddDefaultListLoad(BIZControl.UserList,true);
                }
            }
        }

        /// <summary>
        /// Event när dialogen stänger
        /// </summary>
        /// <param name="sender">ModalaContainern</param>
        /// <param name="e">EventArgs</param>
        void mcEditUser_ModalClosing(object sender, EventArgs e)
        {
            LoadList(false);
        }

        /// <summary>
        /// Event när nya medlemmar har valts att kopplas
        /// </summary>
        /// <param name="sender">Kontrollen</param>
        /// <param name="e">inget</param>
        /// <param name="multipleSelect">flera</param>
        /// <param name="selectedItems">Valda personer</param>
        void NewMembersSelect(object sender, EventArgs e, bool multipleSelect, List<Guid> selectedItems)
        {
            AddUsers(selectedItems);
            LoadList(true);
        }
        #endregion


    }
}